#include <gtest/gtest.h>

/*  
class OrderMeta {
public:
	virtual int selectTo(std::string & sql) = 0;
	virtual int insertTo(std::string & sql) = 0;
	virtual int updateTo(std::string & sql) = 0;
	virtual int replaceTo(std::string & sql) = 0;
	virtual int removeTo(std::string & sql) = 0;
};


class Order : public object<Order>{
public:
	virtual const std::string & key() const {
		return _key;	
	}
	virtual Order & key(const std::string & key) {
		_key = key;
		return *this;
	}
	virtual const st::string & cmd() const{
		return _cmd;
	}
	virtual Order &  cmd(const std::string & cmd){
		_cmd = cmd;
		return *this;
	}

	
	virtual int dmlTo(char * buf , int cap, std::vector<std::pair<char*, size_t>> & result) = 0;
	virtual int selectTo(char * buf, int cap, std::vector<std::pair<char *, size_t>> & result) = 0;

	virtual int insertTo(char * buf , int cap, std::vector<std::pair<char*, size_t>> & result) {
		return dmlTo(buf, cap, result);
	}
	virtual int updateTo(char * buf, int cap, std::vector<std::pair<char *, size_t>> & result) {
		return dmlTo(buf, cap, result);
	}
	virtual int replaceTo(char * buf, int cap, std::vector<std::pair<char *, size_t>> & result) {
		return dmlTo(buf, cap, result);
	}
	virtual int removeTo(char * buf, int cap, std::vector<std::pair<char *, size_t>> & result) {
		return dmlTo(buf, cap, result);
	}


private:
	std::string _key;	
	std::string _cmd;
};


class OrderMeta  {
public:
};

class Buffer {
public:
	virtual int input(const Order & order ) = 0;
	int result() const {
		return _result;
	}
private:
		char _buf[100];	
		int _result; //TODO: [addr, len]
		std::string _sql;
};
class Sql{
public:
	virtual int generate(const ObjectMeta & meta) = 0;
	const std::string & str() const {
		return _str;
	}
private:
	std::string _str;
};

class OrderInserter {
public:
	//input
	class Sql : public :: Sql {
	public:
		int generate(const ObjectMeta & meta) override{
			return meta.insertTo(_sql);
		}
	};
	//output
	class Buffer : public ::Buffer {
	public:
		int input(const Object & object) override{
			return object.insertTo(_buf, 100, _result);
		}
	};


	OrderInserter(const OrderMeta & meta)
	: _meta(meta)
	{
		_sql.generate(_meta);
	}
	Buffer & buffer() {
		return buffer;
	}
	Sql & sql(){
		return _sql;
	}

private:
	OrderMeta & _meta;
	Sql _sql;
	Buffer _buffer;
};

class Transaction {
public:
	virtual int commit() { return 0; }
	virtual int rollback() { return 0; }

	virtual Transaction &  insert(OrderInserter & inserter){
		//sqlite_prepare(inserter.sql().str());
		//sqlite_bind(inserter.buffer());
		//sqlite_execute();
		return *this;
	}
	virtual Transaction & update(Updater & updater){
		//sqlite_prepare(updater.sql().str());
		//sqlite_bind(updater.buffer());
		//sqlite_execute();
		return *this;
	}
	virtual Transaction & remove(Remover & remover){
		//sqlite_prepare(remover.sql().str());
		//sqlite_bind(remover.buffer());
		//sqlite_execute();
		return *this;
	}
	virtual Transaction & selectOne(Selector & selector){
		//sqlite_prepare(selector.sql().str());
		//sqlite_execute();
		//sqlite_fetch(selector.buffer(), 1);
		return *this;
	}
	virtual Iterator * selectMany(Selector & selector, const int rows){
		//sqlite_prepare(selector.sql().str());
		//sqlite_execute();
		//sqlite_fetch(selector.buffer(), );
		return new Iterator(this, selector.buffer());
	}
};
class OrderStorage {
	OrderInserter * _inserter = nullptr;
public:
	OrderStorage(const OrderMeta & meta){	
		_inserter = new OrderInserter(orderMeta); 
	}
	~OrderStorage(){
		delete _inserter;
	}
	
	Result<> insert(const Order & order){
		//TODO: getInserter(order.cmd);
		_inserter->buffer().input(order);
		return _trans->insert(inserter).commit();
	}
	Result<> update(const Order & order) {
		//TODO: getUpdater(order.cmd);
		_updater->buffer().input(order);
		return _trans->update(_updater).commit();
	}
	Result<> replace(const Order & order) {
		//TODO: getReplacer(order.cmd);
		_replacer->buffer().input(order);
		return _trans->replace(_replacer).commit();
	}
	Result<> remove(const Order & order) {
		//TODO: getRemover(order.cmd);
		_remover->buffer().input(order);
		return _trans->remove(_remover).commit();
	}
	Result<> selectOne(const Order & order){
		//TODO: getSelector(order.cmd);
		_selector->buffer().outSize().input(order)
		return _trans->select(_selector).commit();
	}
	Result<> selectMany(Iterator ** iter, const int rows, const Order & order){
		//TODO: getSelector(order.cmd);
		_selector->buffer().outSize(rows).input(order);
		return _trans->select(_selector).commit();
	}
private:
		Transaction * _trans;
};


TEST(OrderTest, testOrder){

	SqliteTransaction sqlite(url);
	OrderMeta meta(filePath);
	OrderStorage ost(sqlite, meta);

	Order order;
	ost.insert(order);
	ost.update(order);
	ost.replace(order);
	ost.remove(order);
	ost.selectOne(order);
	Iterator * iter;
	ost.selectMany(&iter, 100, order);
	iter.foreach([](const auto & item){
		std::cout << "" << std::endl;
	});
	delete iter;
}
*/

TEST(OrderTest, testBatch){
//	OrderStorageBatch ostb;
//	Order orders[10];
//	ostb.batch().replace(orders, 10).commit();
//	ostb.batch().select(orders, 10).commit();
//	ostb.batch().insert(orders, 10).commit();
//	ostb.batch().remove(orders).commit();
}
